import { dialog, IpcMainInvokeEvent } from 'electron';
import { FileType } from '../const';
import Log from './Log';
import path from 'path';
import { app } from 'electron';
import fs from 'fs';
import * as crypto from 'crypto';

const TAG = 'FileUtil';

class FileUtil {
  private static instance: FileUtil;

  public static getInstance() {
    if (!this.instance) {
      this.instance = new FileUtil();
    }
    return this.instance;
  }

  public getResourcePath = () => {
    const RESOURCES_PATH = app.isPackaged
      ? path.join(process.resourcesPath, 'assets')
      : path.join(__dirname, '../../../assets');
    return RESOURCES_PATH;
  };

  public chooseFiles = (event: IpcMainInvokeEvent, fileType: FileType) => {
    return new Promise((resolve, reject) => {
      dialog
        .showOpenDialog({
          title: '请选择两个文件',
          properties: ['openFile', 'multiSelections'],
          filters: [{ name: fileType, extensions: [fileType] }],
        })
        .then(({ canceled, filePaths }) => {
          if (!canceled && filePaths.length > 0) {
            Log.i(TAG, 'success choose files:', filePaths);
            resolve(filePaths);
          } else {
            Log.i(TAG, 'canceled choose files');
          }
        });
    });
  };

  public chooseSingleFile = (event: IpcMainInvokeEvent, fileType: FileType) => {
    return new Promise((resolve, reject) => {
      dialog
        .showOpenDialog({
          title: '请选择一个文件',
          properties: ['openFile', 'openFile'],
          filters: [{ name: fileType, extensions: [fileType] }],
        })
        .then(({ canceled, filePaths }) => {
          if (!canceled && filePaths.length > 0) {
            Log.i(TAG, 'success choose files:', filePaths[0]);
            resolve(filePaths[0]);
          } else {
            Log.i(TAG, 'canceled choose files');
          }
        });
    });
  };

  public chooseDir(event: IpcMainInvokeEvent) {
    return new Promise((resolve, reject) => {
      dialog
        .showOpenDialog({
          title: '请选择文件夹',
          properties: ['openDirectory'],
        })
        .then(({ canceled, filePaths }) => {
          if (!canceled && filePaths.length > 0) {
            Log.i(TAG, 'success choose dir:', filePaths);
            resolve(filePaths[0]);
          } else {
            Log.i(TAG, 'canceled choose dir');
          }
        });
    });
  }

  public verifyCertificate(event: IpcMainInvokeEvent) {
    return new Promise((resolve, reject) => {
      const certificatePath = path.join(
        FileUtil.getInstance().getResourcePath(),
        'encrypt.certificate'
      );
      const priKeyPath = path.join(
        FileUtil.getInstance().getResourcePath(),
        'pri_key.pem'
      );
      if (!fs.existsSync(certificatePath)) {
        reject('证书不存在');
      }
      if (!fs.existsSync(priKeyPath)) {
        reject('私钥不存在');
      }
      const priKey = fs.readFileSync(priKeyPath);
      const certificate = fs.readFileSync(certificatePath);
      const decryptedMessage = crypto.privateDecrypt(
        {
          key: priKey,
          padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
        },
        certificate
      );
      const expireTimeStr = JSON.parse(decryptedMessage.toString())[
        'expire_time'
      ];
      const expireTime = new Date(expireTimeStr);
      const now = new Date();
      Log.i(now, expireTime);
      if (now < expireTime) {
        resolve('');
      }
      reject('校验不通过');
    });
  }

  public importCertificate(event: IpcMainInvokeEvent, filePath: string) {
    return new Promise((resolve, reject) => {
      Log.i(TAG, `导入证书路径：${filePath}`);
      const destPath = path.join(
        FileUtil.getInstance().getResourcePath(),
        'encrypt.certificate'
      );
      Log.i(TAG, `目标路径：${destPath}`);
      fs.copyFile(filePath, destPath, (err) => {
        if (err) {
          Log.e(err);
        } else {
          resolve('');
        }
      });
    });
  }
}
export default FileUtil;
